﻿//----------------------------------------------------------------
// Desc: 
// Edit: ShowLong, http://blog.csdn.net/showlong
//
// Date Created: 2011-10-26
//
// Update Date : 
//
// Copyright (c) Fuel4D (http://www.fuel4d.com), All rights reserved.
//
// 使用方法：
//    IFADO* ado = FNewADO();
//    if (ado->Open(_T("127.0.0.1"), _T("db_name"), _T("sa"), _T("123456")))
//    {
//        // 方式一：自动查询并自动关闭结果集
//        {
//            FADO_AutoRet rec(ado, _T("SELECT * FROM [table_name]"));
//            if (rec)
//            {
//                rec->MoveFirst();
//                while(!rec->IsEOF())
//                {
//                    int id = rec->GetInt(_T("role_id"));
//                    rec->MoveNext();
//                }
//            }
//        }
//        // 方式二：手动查询并手动关闭结果集
//        {
//            IFADO_Recordset* rec = ado->Execute(_T("SELECT * FROM [table_name]"));
//            if (rec)
//            {
//                rec->MoveFirst();
//                while(!rec->IsEOF())
//                {
//                    int id = rec->GetInt(_T("role_id"));
//                    rec->MoveNext();
//                }
//                ado->DestroyRecord(rec);
//            }
//        }
//    }
//    FDelADO(ado);
//----------------------------------------------------------------
#pragma once


#if FUEL_OS_WINDOWS


class IFADO_Recordset;
class IFADO;
class FADO_AutoRet;


//----------------------------------------------------------------
//
//----------------------------------------------------------------
class IFADO_Recordset : public IFMemObject
{
protected:
    explicit IFADO_Recordset(){}

public:
    // 获取字段值
    virtual WCHAR* GetChar(const WCHAR* szField) = 0;
    virtual float GetReal(const WCHAR* szField) = 0;
    virtual int GetInt (const WCHAR* szField) = 0;
    virtual INT64 GetInt64(const WCHAR* szField) = 0;
    virtual double GetDouble(const WCHAR* szField) = 0;
    // 获取记录条数
    virtual int GetCount() = 0;
    // 游标向后移动一次
    virtual bool MoveNext() = 0;
    // 游标移至最顶端
    virtual bool MoveFirst() = 0;
    // 游标记录是否为空
    virtual bool IsEmpty() = 0;
    // 游标是否已至最后
    virtual bool IsEOF() = 0;
    // 游标是否打开
    virtual bool IsOpen() = 0;
};


//----------------------------------------------------------------
//
//----------------------------------------------------------------
class IFADO : public IFMemObject
{
protected:
    explicit IFADO(){}

public:
    // 打开一个连接
    virtual bool Open(const WCHAR* szIP, const WCHAR* szDBName, const WCHAR* szUserName,  const WCHAR* szPassword) = 0;
    // 直接使用连接字串
    virtual bool Open(const WCHAR* szConnectString) = 0;
    // 使用DSN连接
    virtual bool Open(const WCHAR* szDSN, const WCHAR* szUserName, const WCHAR* szPassword) = 0;
    // 重新连接
    virtual bool ReOpen() = 0;
    // 执行SQL语句并返回结果集
    virtual IFADO_Recordset* Execute(const WCHAR* szCmd) = 0;
    // 释放结果集的控制
    virtual void DestroyRecord(IFADO_Recordset*& pRec) = 0;
    // 检测连接是否打开
    virtual bool IsOpen() = 0;
    // 关闭连接
    virtual void Close() = 0;
};


//----------------------------------------------------------------
//
//----------------------------------------------------------------
class FADO_AutoRet
{
public:
    FADO_AutoRet(IFADO* con, const WCHAR* cmd)
    {
        pCon = con;
        pRec = 0;
        if (pCon)
            pRec = pCon->Execute(cmd);
    }
    ~FADO_AutoRet()
    {
        if (pCon && pRec)
            pCon->DestroyRecord(pRec);
    }

    operator bool(){ return pRec != 0; }
    operator IFADO_Recordset*(){ pRec; }
    IFADO_Recordset* operator->(){ return pRec; }

protected:
    IFADO* pCon;
    IFADO_Recordset* pRec;
};


extern FAPI IFADO* FNewADO(FNEW_FUNC_API);


#endif